#pragma once
#include "FXParameter.h"
#include "util.h"
#include <map>
#include <vector>

class ShaderParameter;
class Technique;

/**
* Abstraction of the Effect concept.
* The DirectX project implements this as a HLSLEffect.
* The OpenGL project implements this as an OpenGLEffect.
* @author Koen Samyn
*/
class Effect
{
public:
	/**
	* Creates a new Effect object.
	*/
	Effect(void);
	/**
	* Destroys the Effect object.
	*/
	virtual ~Effect(void);
	/**
	* Gets a specifice technique by name.
	* @param name the name of the technique.
	* @return the requested technique, NULL if the technique was not found.
	*/
	Technique* GetTechnique(tstring name) const;
	/**
	* Add a technique to the map of techniques.
	* @param technique the technique object to add.
	*/
	void AddTechnique(Technique* technique);
	/**
	* Iterates through the techniques and returns the parameter if found.
	* This parameter should be a shared parameter.
	* @param name the name for the parameter.
	* @return the ShaderParameter pointer, NULL if no parameter was found
	* with the specified name.
	*/
	FXParameter* FindParameterByName(const tstring& name) const;
	/**
	* Iterates through the techniques and returns the parameter.
	* This parameter should be a shared parameter.
	* @param name the semantic of the parameter.
	* @return the ShaderParameter pointer, NULL if no parameter was found
	* with the specified name.
	*/
	FXParameter* FindParameterBySemantic(const tstring& name) const;
protected:
	/**
	* Map with the techniques that are defined in the shader
	* file.
	*/
	map<tstring, Technique*> m_TechniqueMap;
	/**
	* Adds a parameter to the list of parameters.
	* @param parameter the parameter to add.
	*/
	void AddParameter(FXParameter* parameter);
private:
	typedef map<tstring,Technique*>::const_iterator TechIt;
	/**
	* vector with all the parameters defined in the effect.
	* The Effect object maintains ownership of all non customized shader parameters.
	*/
	vector<FXParameter*> m_AllParameters;
	// -------------------------
	// Disabling default copy constructor and default assignment operator.
	// If you get a linker error from one of these functions, your class is internally trying to use them. This is
	// an error in your class, these declarations are deliberately made without implementation because they should never be used.
	// -------------------------
	Effect(const Effect& t);
	Effect& operator=(const Effect& t);
};
